/** @file pra_matrix.h
    @brief Function prototypes for the matrix 
    This contains the prototypes for the pra_matrix
    @version 0.0.1
    @author prabhakar pujeri
    email:prabhakar.pujeri@gmail.com
    @bug No known bugs.
 */

#ifndef pra_matrix_H
#define pra_matrix_H

#include <stdlib.h>
#include <errno.h>
#include <math.h>

/**
    @typedef pra_matrix
    @brief pra_matrix is the data type of matrix.\ 
    It has member matrix its integer pointer it ponts to the memory where 
    matrix row and colloums are allocated and row is the numer of rows 
    in matrix and  col is number of collum in the matrix
    

*/
typedef struct pra_matrix {
	double *matrix; /**< matrix data pointer */
	int row; /**< number of rows in matrix */
	int col; /**< number of colloums in matrix */
}pra_matrix;

/**
    @brief allocate matrix depend up on argument row and coloum 
    @param row number of row in matrix 
    @param col number of coloum in matrix 
    @return pra_matrix* return  pra_matrix pointer
*/
pra_matrix* pra_matrix_alloc ( int row, int col );

/**
    @brief free matrix will free matrix it takes only pointer of matrix 
    @param pra_matrix* pra_matrix pointer 
    @return void
    
*/
void  pra_matrix_free ( pra_matrix* );

/**
    @brief this function reads input from STDIN and stores in matix 
    @param pra_matrix* pra_matrix pointer
    @return void 

*/
pra_matrix*  pra_matrix_input ( pra_matrix* );

/**
    @brief this function write to STDOUT of pra_matrix
    @param pra_matrix matrix pointer
    @return void 
*/
void  pra_matrix_output ( pra_matrix * );

/**
    @brief addition of two matrix
    @param pra_matrix* first matrix pointer for addition 
    @param pra_matrix* second matrix pointer for addtion 
    @param pra_matrix* result of addition of two matrix stored in C
    @return void
*/
void  pra_matrix_add ( pra_matrix*, pra_matrix*, pra_matrix* );

/**
    @brief addition of matrix with constant
    @param pra_matrix* first matrix pointer for addition 
    @param double constant value 
    @param pra_matrix* result of addition of constant to the matrix
    @return void
*/
void pra_matrix_add_const ( pra_matrix *, double, pra_matrix * );
/**
    @brief substration of two matrix 
    @param pra_matrix*A first pra_matrix pointer for substraction 
    @param pra_matrix*B second pra_matrix pointer for substraction
    @param pra_matrix*C result of substraction of two matrix stored in C
    @return void 
*/
void  pra_matrix_sub ( pra_matrix*, pra_matrix*, pra_matrix* );
/**
    @brief substration of matrix with constant
    @param pra_matrix* first matrix pointer for addition 
    @param double constant value 
    @param pra_matrix* result of addition of constant to the matrix
    @return void
*/
void pra_matrix_sub_const ( pra_matrix *, double, pra_matrix * );
/**
    @brief multiplication of two matrix 
    @param pra_matrix*A first pra_matrix pointer for multiplication
    @param pra_matrix*B second pra_matrix pointer for multiplication
    @param pra_matrix*C result of multipication of two matrix stored in C
    @return void 
*/
void  pra_matrix_multi ( pra_matrix*, pra_matrix*, pra_matrix* );

/**
    @brief dot product of two matrix 
    @param pra_matrix*A first pra_matrix pointer for dot product
    @param pra_matrix*B second pra_matrix pointer for dot product
    @param pra_matrix*C result of dot product  of two matrix stored in C
    @return void 
*/
void pra_matrix_dot_product ( pra_matrix*, pra_matrix*, pra_matrix* );

/**
    @brief scalar product of pra_matrix
    @param pra_matrix*A pra_matrix for scalar product
    @param double  scalar value
    @param pra_matrix* scalar product result  pra_matrix
    @return void 
    
*/
void pra_matrix_scalar_product ( pra_matrix*, double, pra_matrix* );
/**
    @brief determinat od square matrix
    @param pra_matrix*A  the matrix pointer for determinat
    @param int  order of squrematrix 
    @return double returns determinat of pra_matrix
*/
double pra_matrix_determinant ( pra_matrix*,int );

/**
    @brief transfose of matrix
    @param pra_matrix*A pra_matrix for transfose
    @param int  order of matrix
    @param pra_matrix*T transpose pra_matrix A
    @return void 
*/
void pra_matrix_transpose ( pra_matrix*, int, pra_matrix* );

/**
    @brief co-Factor of matrix
    @param pra_matrix*A pra_matrix for co factor
    @param int  order of matrix
    @param pra_matrix*T cofactor of  pra_matrix A
    @return void 
*/
void pra_matrix_co_factor( pra_matrix*, int, pra_matrix* );


/**
    @brief adjoint of matrix
    @param pra_matrix* pra_matrix for adjoint
    @param int  order of matrix
    @param pra_matrix* adjoint of  pra_matrix A
    @return void 
*/
void pra_matrix_adjoint (pra_matrix*,pra_matrix*);

/**
    @brief inverse of pra_matrix
    @param pra_matrix*A pra_matrix for co factor
    @param pra_matrix*I inverse  of  pra_matrix A
    @return void 
*/

void pra_matrix_inverse ( pra_matrix*, pra_matrix* );


/**
    @brief equal of two matrix
    
    @param pra_matrix* first matrix
    @param pra_matrix* second matrix
    @return 0 if both matrix are equal else greter then 0
*/

int pra_matrix_equal (pra_matrix *,pra_matrix *);
/**
    @brief checks symmetric of the matrics
    @param pra_matrix* test metrix
    @return  0 if symmetric else return 1 
*/
int pra_matrix_symmetric (pra_matrix *);
/**
    @brief maximum number in matrix
    @param pra_matrix* input matrix
    @return  maximum number in matrix
    @todo
*/
double pra_matrix_max ( pra_matrix*);
/**
    @brief initialize matrix to one
    @param pra_matrix*A pra_matrix pointer for initialize matrix to Zero
    @return void 
*/
pra_matrix* pra_matrix_identity(int);
/**
    @brief minimum number in matrix
    @param pra_matrix* input matrix
    @return  minumum number in matrix 
    @todo
*/
double pra_matrix_min ( pra_matrix*);
/**
    @brief maximum number index in matrix
    @param pra_matrix* input matrix
    @return maximum number index  
    @todo
*/
int pra_matrix_max_index( pra_matrix* );
/**
    @brief minimum number index
    @param pra_matrix* input matrix
    @return minimum number index  
    @todo
*/
int pra_matrix_min_index ( pra_matrix* );
/**
    @brief checks is it null matrix 
    @param pra_matrix* input matrix
    @return 0 if null matrix 
    @todo
*/
int pra_matrix_is_null ( pra_matrix* );
/**
    @brief checks all values in matrix are positive 
    @param pra_matrix* input matrix
    @return 0 if all values in matrix are positive 
    @todo
*/
int pra_matrix_is_pos ( pra_matrix* );
/**
    @brief checks all values in matrix are negative 
    @param pra_matrix* input matrix
    @return 0 if all values in matrix are negative  
    @todo
*/
int pra_matrix_is_neg ( pra_matrix* );
void pra_matrix_set_to_null (pra_matrix *);


#endif 
